【劳动节献礼】Emacs插件的威力 动态的将C/C++代码转换为汇编代码
;; **************************************************************************************************************;; Author: zklhp
;; Email: zklhp@
;; QQ: 493165744
;; Last update: 2013.5.1
;; Licensed under CC-BY-SA 3.0
;; **************************************************************************************************************
闲话不说 上图
获取方法很简单 这个东西已经进入ELPA了 直接安装就可以了 相对来说配置难道不高
程序代码:
(eval-after-load 'cc-mode '(progn (require 'disaster) (defun my-c-mode-common-hook () (define-key c-mode-base-map (kbd "C-c C-d") 'disaster) ) (add-hook 'c-mode-common-hook 'my-c-mode-common-hook)))
稍微配置一下 现在摁一下就能看汇编代码了
来个复杂点的例子 这个东西可以改编译等级哦 如果这样的话看代码优化就很方便了 嘻嘻
下面这个例子用-O3编译看看
程序代码:
#include <math.h> // smallpt, a Path Tracer by Kevin Beason, 2008 #include <stdlib.h> // Make : g++ -O3 -fopenmp smallpt.cpp -o smallpt #include <stdio.h> // Remove "-fopenmp" for g++ version < 4.2 #include <time.h> #ifdef __MSC_VER #define INLINE __forceinline //#define INLINE __declspec(noinline) #else #define INLINE inline #endif #ifndef M_PI #define M_PI 3.141592653589793238462643 #endif class RandomLCG { unsigned mSeed; public: INLINE RandomLCG(unsigned seed = 0) : mSeed(seed) { } INLINE double operator()() { mSeed = 214013u * mSeed + 2531011u; return mSeed * (1.0 / 4294967296.0); } }; struct Vec { double x, y, z; static const Vec Zero; static const Vec XAxis; static const Vec YAxis; static const Vec ZAxis; INLINE Vec(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) { } INLINE Vec operator+(const Vec& b) const { return Vec(x + b.x, y + b.y,z + b.z); } INLINE Vec operator-(const Vec& b) const { return Vec(x - b.x, y - b.y, z - b.z); } INLINE Vec operator*(double b) const { return Vec(x * b, y * b, z * b); } friend INLINE Vec operator*(const Vec& a, const Vec& b) { return Vec(a.x * b.x , a.y * b. y, a.z * b.z); } INLINE Vec norm() const { return *this * (1.0 / sqrt(x * x + y * y + z * z)); } INLINE double operator%(const Vec& b) const { // dot return x * b.x + y * b.y + z * b.z; } INLINE Vec operator^(const Vec& b) const { // cross return Vec(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); } }; const Vec Vec::Zero(0, 0, 0); const Vec Vec::XAxis(1, 0, 0); const Vec Vec::YAxis(0, 1, 0); const Vec Vec::ZAxis(0, 0, 1); struct Ray { Vec o, d; INLINE Ray(const Vec &o, const Vec &d) : o(o), d(d) { } }; // material types, used in radiance() enum Refl_t { DIFF, SPEC, REFR }; struct Sphere { Vec p, e, c; // position, emission, color Vec cc; double rad; // radius double sqRad; double maxC; Refl_t refl; // reflection type (DIFFuse, SPECular, REFRactive) Sphere(double rad, const Vec& p, const Vec& e, const Vec& c, Refl_t refl) : p(p), e(e), c(c), rad(rad), refl(refl) { sqRad = rad * rad; maxC = c.x > c.y && c.y > c.z ? c.x : c.y > c.z ? c.y : c.z; cc = c * (1.0 / maxC); } // returns distance, 1e20 if nohit INLINE double intersect(const Ray &r) const { // Solve t^2*d.d + 2*t*(o-p).d + (o-p).(o-p)-R^2 = 0 Vec op = p - r.o; double b = op % r.d; double det = b * b - op % op + sqRad; const double eps = 1e-4; if (det < 0) return 1e20; else { double dets = sqrt(det); if (b - dets > eps) return b - dets; else if (b + dets > eps) return b + dets; else return 1e20; } } }; //Scene: radius, position, emission, color, material static Sphere spheres[] = { Sphere(1e5, Vec( 1e5+1,40.8,81.6), Vec::Zero, Vec(.75,.25,.25), DIFF),//Left Sphere(1e5, Vec(-1e5+99,40.8,81.6), Vec::Zero, Vec(.25,.25,.75), DIFF),//Rght Sphere(1e5, Vec(50,40.8, 1e5), Vec::Zero, Vec(.75,.75,.75), DIFF),//Back Sphere(1e5, Vec(50,40.8,-1e5+170), Vec::Zero, Vec::Zero, DIFF),//Frnt Sphere(1e5, Vec(50, 1e5, 81.6), Vec::Zero, Vec(.75,.75,.75), DIFF),//Botm Sphere(1e5, Vec(50,-1e5+81.6,81.6), Vec::Zero, Vec(.75,.75,.75), DIFF),//Top Sphere(16.5, Vec(27,16.5,47), Vec::Zero, Vec(1,1,1)*.999, SPEC),//Mirr Sphere(16.5, Vec(73,16.5,78), Vec::Zero, Vec(1,1,1)*.999, REFR),//Glas Sphere(600, Vec(50,681.6-.27,81.6), Vec(12,12,12), Vec::Zero, DIFF) //Lite }; INLINE double clamp(double x) { if (x < 0) return 0; else if (x > 1) return 1; else return x; } INLINE int toInt(double x) { return int(pow(clamp(x), 1 / 2.2) * 255 + .5); } INLINE Sphere* intersect(const Ray &r, double &t) { t = 1e20; Sphere* ret = NULL; for (Sphere* s = spheres; s != spheres + sizeof(spheres) / sizeof(Sphere); ++s) { double d = s->intersect(r); if (d < t) { t = d; ret = s; } } return ret; } static Vec radiance(const Ray &r, int depth, RandomLCG& rand) { double t; // distance to intersection Sphere* obj = intersect(r, t); if (!obj) return Vec::Zero; // if miss, return black else { int newDepth = depth + 1; bool isMaxDepth = newDepth > 100; // Russian roulette for path termination bool isUseRR = newDepth > 5; bool isRR = isUseRR && rand() < obj->maxC; if (isMaxDepth || (isUseRR && !isRR)) return obj->e; else { Vec f = (isUseRR && isRR) ? obj->cc : obj->c; Vec x = r.o + r.d * t; Vec n = (x - obj->p).norm(); Vec nl = n % r.d < 0 ? n : n * -1; if (obj->refl == DIFF) { // Ideal DIFFUSE reflection double r1 = 2 * M_PI * rand(); double r2 = rand(); double r2s = sqrt(r2); Vec w = nl; Vec wo = w.x < -0.1 || w.x > 0.1 ? Vec::YAxis : Vec::XAxis; Vec u = (wo ^ w).norm(); Vec v = w ^ u; Vec d = (u * cos(r1) * r2s + v * sin(r1) * r2s + w * sqrt(1 - r2)).norm(); return obj->e + f * radiance(Ray(x, d), newDepth, rand); } else if (obj->refl == SPEC) // Ideal SPECULAR reflection return obj->e + f * radiance(Ray(x, r.d - n * (2 * (n % r.d))), newDepth, rand); else { // Ideal dielectric REFRACTION Ray reflRay(x, r.d - n * (2 * (n % r.d))); bool into = n % nl > 0; // Ray from outside going in? double nc = 1; double nt = 1.5; double nnt = into ? nc / nt : nt / nc; double ddn = r.d % nl; double cos2t = 1 - nnt * nnt * (1 - ddn * ddn); if (cos2t < 0) // Total internal reflection return obj->e + f * radiance(reflRay, newDepth, rand); else { Vec tdir = (r.d * nnt - n * ((into ? 1 : -1) * (ddn * nnt + sqrt(cos2t)))).norm(); double a = nt - nc; double b = nt + nc; double R0 = (a * a) / (b * b); double c = 1 - (into ? -ddn : tdir % n); double Re = R0 + (1 - R0) * c * c * c * c * c; double Tr = 1 - Re; double P = .25 + .5 * Re; double RP = Re / P; double TP = Tr / (1 - P); Vec result; if (newDepth > 2) { // Russian roulette and splitting for selecting reflection and/or refraction if (rand() < P) result = radiance(reflRay, newDepth, rand) * RP; else result = radiance(Ray(x, tdir), newDepth, rand) * TP; } else result = radiance(reflRay, newDepth, rand) * Re + radiance(Ray(x, tdir), newDepth, rand) * Tr; return obj->e + f * result; } } } } } int main(int argc, char *argv[]) { clock_t start = clock(); const int w = 256; const int h = 256; const int samps = argc == 2 ? atoi(argv[1]) / 4 : 25; // # samples const Ray cam(Vec(50, 52, 295.6), Vec(0, -0.042612, -1).norm()); // cam pos, dir const Vec cx(w * .5135 / h); const Vec cy = (cx ^ cam.d).norm() * .5135; Vec* c = new Vec[w * h]; #pragma omp parallel for schedule(dynamic, 1) // OpenMP // Loop over image rows for (int y = 0; y < h; y++) { fprintf(stderr,"\rRendering (%d spp) %5.2f%%",samps*4,100.*y/(h-1)); RandomLCG rand(y); // Loop cols for (unsigned short x=0; x<w; x++) { // 2x2 subpixel rows for (int sy = 0; sy < 2; sy++) { const int i = (h - y - 1) * w + x; // 2x2 subpixel cols for (int sx = 0; sx < 2; sx++) { Vec r = Vec::Zero; for (int s = 0; s < samps; s++) { double r1 = 2 * rand(); double r2 = 2 * rand(); double dx = r1 < 1 ? sqrt(r1) - 1 : 1 - sqrt(2 - r1); double dy = r2 < 1 ? sqrt(r2) - 1 : 1 - sqrt(2 - r2); Vec d = cx * (((sx + .5 + dx) / 2 + x) / w - .5) + cy * (((sy + .5 + dy) / 2 + y) / h - .5) + cam.d; r = r + radiance(Ray(cam.o + d * 140, d.norm()), 0, rand) * (1.0 / samps); } c[i] = c[i] + Vec(clamp(r.x), clamp(r.y), clamp(r.z)) * .25; } } } } printf("\n%f sec\n", (float)(clock() - start) / CLOCKS_PER_SEC); FILE *f = fopen("image.ppm", "w"); // Write image to PPM file. fprintf(f, "P3\n%d %d\n%d\n", w, h, 255); for (int i = 0; i < w * h; i++) fprintf(f,"%d %d %d\n", toInt(c[i].x), toInt(c[i].y), toInt(c[i].z)); fclose(f); }
用上SSE了 不错 可惜不知道为啥效率并不好
以上的都是在Archlinux x86_64 环境下进行的 windows下也可以 当然你就不止要有Emacs了 还得有MinGW。。。
欢迎大家使用神的编辑器Emacs